﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.HVAC;
using YArchitech.MEP;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using Transfer.Utils;

namespace YArchitech.Plumbing
{
	public class RiserPipeOperation
	{
		public void SetParament(ref double zStart, ref double zEnd, ref PipeType pipeTypeRiser, ref PipingSystemType pipingSystemTypeRiser, ref string diameter, FormReiseDrawVerticalPipe drawPipeForm)
		{
			zStart = drawPipeForm.zStart;
			zEnd = drawPipeForm.zEnd;
			pipeTypeRiser = drawPipeForm.pipeTypeRiser;
			pipingSystemTypeRiser = drawPipeForm.pipingSystemTypeRiser;
			diameter = drawPipeForm.diameter;
		}

		public void SetMark(Pipe RiserPipe, UIDocument uidoc, FormReiseDrawVerticalPipe drawPipeForm, UIApplication uiApp, AuxiliaryFrameOperation afOperation)
		{
			using (CreateRiserPipeLinesJig createRiserPipeLinesJig = new CreateRiserPipeLinesJig(uidoc))
			{
				RiserPipeAndCenter riserPipeAndCenter;
				XYZ xyz;
				XYZ xyz2;
				XYZ xyz3;
				string empty;
				string empty2;
				do
				{
					XYZ riserPipeCenter = this.GetRiserPipeCenter(RiserPipe, uidoc);
					riserPipeAndCenter = new RiserPipeAndCenter(RiserPipe, riserPipeCenter);
					createRiserPipeLinesJig.StartPoint = riserPipeCenter;
					xyz = null;
					xyz2 = null;
					xyz3 = uidoc.Selection.PickPoint("请选择标注位置：");
					empty = string.Empty;
					empty2 = string.Empty;
				}
				while (!this.setPipeParameter(ref empty, ref empty2, drawPipeForm));
				MarkRiserPipeUtility.SetRiserPipeParameters(uiApp, riserPipeAndCenter.RiserPipe, empty, empty2, drawPipeForm.rbCuston.Checked, false);
				double num = 0.0;
				double lineLength = this.getLineLength(uidoc, riserPipeAndCenter, ref num);
				num = (num - (double)(130 * uidoc.Document.ActiveView.Scale / 100)) / 304.8;
				DetailCurveArray detailCurveArr = this.getDetailCurveArr(uidoc, riserPipeAndCenter, lineLength, ref xyz, xyz3, ref xyz2, createRiserPipeLinesJig.isLeft);
				if (detailCurveArr != null)
				{
					xyz3 = new XYZ(xyz3.X, xyz3.Y, uidoc.Document.ActiveView.GenLevel.Elevation);
					XYZ xyz4 = new XYZ(1.0, 0.0, 0.0);
					if (createRiserPipeLinesJig.isLeft)
					{
						xyz4 = new XYZ(-1.0, 0.0, 0.0);
					}
					XYZ textLocation = xyz3.Add(xyz4 * lineLength / 304.8 / 2.0).Add(new XYZ(0.0, 1.0, 0.0) * 0.5 * num);
                    Autodesk.Revit.DB.Group group = this.createGroup(detailCurveArr, uidoc, riserPipeAndCenter, afOperation, RiserPipe);
					MarkRiserPipeUtility.MarkSinglePipeText(uidoc.Document, uidoc.Document.ActiveView, riserPipeAndCenter.RiserPipe, textLocation, drawPipeForm.cbDistrict.Checked, drawPipeForm.cbBuild.Checked, group);
					new List<Pipe>().Add(riserPipeAndCenter.RiserPipe);
					uidoc.Document.Regenerate();
				}
			}
		}

		private bool setPipeParameter(ref string areaAndFloor, ref string customNumber, FormReiseDrawVerticalPipe drawPipeForm)
		{
			string str = string.Empty;
			string str2 = string.Empty;
			if (drawPipeForm.cbDistrict.Checked)
			{
				if (drawPipeForm.hyTextBox3.Text == "" || !Regex.IsMatch(drawPipeForm.hyTextBox3.Text, "^[A-Za-z0-9'_]+$"))
				{
					YJKMessageBox.Warning("文本框值不能为空且必须由英文字母、数字或'_组成！");
					drawPipeForm.hyTextBox3.Focus();
					return false;
				}
				str = drawPipeForm.hyTextBox3.Text + "-";
			}
			if (drawPipeForm.cbBuild.Checked)
			{
				if (drawPipeForm.hyTextBox4.Text == "" || !Regex.IsMatch(drawPipeForm.hyTextBox4.Text, "^[A-Za-z0-9'_]+$"))
				{
					YJKMessageBox.Warning("文本框值不能为空且必须由英文字母、数字或'_组成！");
					drawPipeForm.hyTextBox4.Focus();
					return false;
				}
				str2 = drawPipeForm.hyTextBox4.Text + "-";
			}
			if (drawPipeForm.rbCuston.Checked && (drawPipeForm.hyTextBox2.Text == "" || !Regex.IsMatch(drawPipeForm.hyTextBox2.Text, "^[A-Za-z0-9'_]+$")))
			{
				YJKMessageBox.Warning("文本框值不能为空且必须由英文字母、数字或'_组成！");
				drawPipeForm.hyTextBox2.Focus();
				return false;
			}
			areaAndFloor = str + str2;
			customNumber = drawPipeForm.hyTextBox2.Text;
			return true;
		}

        private Autodesk.Revit.DB.Group createGroup(DetailCurveArray detailCurveArr, UIDocument uidoc, RiserPipeAndCenter pipeAndCenter, AuxiliaryFrameOperation afOperation, Pipe RiserPipe)
		{
			List<RiserPipeAndCenter> list = new List<RiserPipeAndCenter>();
			list.Add(pipeAndCenter);
            Autodesk.Revit.DB.Group group = MarkRiserPipeUtility.WriteMarkGroupsToRiserPipe(uidoc.Document, list, detailCurveArr);
            AssociationMarkInfo.WriteMarkInfoToElement(group, YArchitech.HVAC.MarkType.RiserPipe);
			afOperation.SetAuxiliaryFramePipeGroup(uidoc.Document, RiserPipe, group);
			return group;
		}

		private DetailCurveArray getDetailCurveArr(UIDocument uidoc, RiserPipeAndCenter pipeAndCenter, double markingTextLength, ref XYZ textLocation, XYZ ptLocation, ref XYZ subLineDir, bool isleft)
		{
			List<Line> list = MarkRiserPipeUtility.DrawSinglePipeMarkLines(pipeAndCenter.Location, ptLocation, 0.0, false, Math.Abs(AssistFunc.feetToMM(ptLocation.Y - pipeAndCenter.Location.Y)), markingTextLength, ref textLocation, ref subLineDir, uidoc.Document, isleft);
			DetailCurveArray detailCurveArray = new DetailCurveArray();
			if (list.Count == 0)
			{
				return null;
			}
			foreach (Curve curve in list)
			{
				DetailCurve detailCurve = uidoc.Document.Create.NewDetailCurve(uidoc.ActiveView, curve);
				detailCurveArray.Append(detailCurve);
			}
			return detailCurveArray;
		}

		private double getLineLength(UIDocument uidoc, RiserPipeAndCenter pipeAndCenter, ref double height)
		{
			string markFamilyPath = UnifiedModified.GetMarkFamilyPath(uidoc.Document, "HY_水管立管标记");
			uidoc.Document.LoadFamily(markFamilyPath);
			FamilySymbol familySymbol = YJKRevitTools.GetFamilySymbol(uidoc.Document, "HY_水管立管标记", BuiltInCategory.OST_PipeTags);
			IndependentTag independentTag = uidoc.Document.Create.NewTag(uidoc.Document.ActiveView, pipeAndCenter.RiserPipe, false, 0, 0, new XYZ(0.0, 0.0, 0.0));
			independentTag.ChangeTypeId(familySymbol.Id);
            YArchitech.HVAC.MarkOperation markOperation = new MarkOperation();
			double width = 0.0;
			markOperation.GetTagTextWidthAndHeight(independentTag.TagText, uidoc.Document, ref width, ref height);
			double widthByRevitVersion = this.GetWidthByRevitVersion(uidoc.Document, width, independentTag.TagText);
			uidoc.Document.Delete(independentTag.Id);
			return widthByRevitVersion;
		}

		private double GetWidthByRevitVersion(Document doc, double width, string textValue)
		{
			if (RevitVersion.Version == "2016" || RevitVersion.Version == "2017")
			{
				if (doc.ActiveView.Scale <= 100)
				{
					if (doc.ActiveView.Scale == 100)
					{
						width += (double)(100 * doc.ActiveView.Scale / 100);
					}
					else
					{
						width += (double)(7500 / doc.ActiveView.Scale);
					}
				}
			}
			else if (RevitVersion.Version == "2015" || RevitVersion.Version == "2014")
			{
				width *= 95.0;
			}
			else if (RevitVersion.Version == "2018")
			{
				if (doc.ActiveView.Scale >= 100)
				{
					width += (double)(200 * doc.ActiveView.Scale / 100);
				}
				else
				{
					width += (double)(10000 / doc.ActiveView.Scale);
				}
			}
			return width;
		}

        private void setMarkToOtherLevel(List<Autodesk.Revit.DB.View> otherViews, XYZ ptLocation, List<Pipe> curPipes, UIDocument uidoc, DetailCurveArray detailCurveArr, Autodesk.Revit.DB.Group group, RiserPipeAndCenter pipeAndCenter, double markingTextLength, XYZ textLocation, XYZ subLineDir, FormReiseDrawVerticalPipe drawPipeForm, double height, bool isleft)
		{
			foreach (Autodesk.Revit.DB.View view in otherViews)
			{
				if (view.GenLevel != null)
				{
					XYZ location = new XYZ(ptLocation.X, ptLocation.Y, view.GenLevel.Elevation);
					List<RiserPipeAndCenter> riserPipePointsInSpecifiedView = this.GetRiserPipePointsInSpecifiedView(view, curPipes, location, uidoc);
					if (riserPipePointsInSpecifiedView != null && riserPipePointsInSpecifiedView.Count > 0)
					{
						detailCurveArr.Clear();
						foreach (Curve curve in MarkRiserPipeUtility.DrawSinglePipeMarkLines(riserPipePointsInSpecifiedView[0].Location, location, 0.0, false, Math.Abs(AssistFunc.feetToMM(ptLocation.Y - pipeAndCenter.Location.Y)), markingTextLength, ref textLocation, ref subLineDir, uidoc.Document, isleft))
						{
							DetailCurve detailCurve = uidoc.Document.Create.NewDetailCurve(view, curve);
							detailCurveArr.Append(detailCurve);
						}
						group = MarkRiserPipeUtility.WriteMarkGroupsToRiserPipe(uidoc.Document, riserPipePointsInSpecifiedView, detailCurveArr);
                        AssociationMarkInfo.WriteMarkInfoToElement(group, YArchitech.HVAC.MarkType.RiserPipe);
						MarkRiserPipeUtility.MarkSinglePipeText(uidoc.Document, view, riserPipePointsInSpecifiedView[0].RiserPipe, textLocation, subLineDir, markingTextLength, drawPipeForm.cbDistrict.Checked, drawPipeForm.cbBuild.Checked, group, height);
					}
				}
			}
		}

		private List<RiserPipeAndCenter> GetRiserPipePointsInSpecifiedView(View view, List<Pipe> pipes, XYZ location, UIDocument uidoc)
		{
			List<RiserPipeAndCenter> list = new List<RiserPipeAndCenter>();
			double elevation = view.GenLevel.Elevation;
			foreach (Pipe pipe in pipes)
			{
				foreach (Pipe pipe2 in this.GetConnectedPipes(pipe, uidoc))
				{
					Line curve = (pipe2.Location as LocationCurve).Curve as Line;
					XYZ xyz = curve.GetEndPoint(0);
					XYZ xyz2 = curve.GetEndPoint(1);
					if (xyz.Z > xyz2.Z)
					{
						XYZ xyz3 = xyz;
						xyz = xyz2;
						xyz2 = xyz3;
					}
					if (Geometry.Lessthan_Or_Equal(xyz.Z, elevation) && Geometry.Greaterthan_Or_Equal(xyz2.Z, elevation))
					{
						XYZ point = new XYZ(xyz.X, xyz.Y, elevation);
						RiserPipeAndCenter item = new RiserPipeAndCenter(pipe2, point);
						list.Add(item);
						Parameter parameter = pipe.GetParameter("立管编号");
						if (parameter != null && parameter.HasValue)
						{
							string text = parameter.AsString();
							parameter = pipe2.GetParameter("立管编号");
							if (parameter != null)
							{
								parameter.Set(text);
							}
						}
						Parameter parameter2 = pipe.GetParameter("区号楼号");
						if (parameter2 != null && parameter2.HasValue)
						{
							string text2 = parameter2.AsString();
							parameter2 = pipe2.GetParameter("区号楼号");
							if (parameter2 != null)
							{
								parameter2.Set(text2);
							}
						}
					}
				}
			}
			int count = list.Count;
			return MarkRiserPipeUtility.SortPoints(list, location);
		}

		protected List<Pipe> GetConnectedPipes(Pipe pipe, UIDocument uidoc)
		{
			List<Pipe> list = new List<Pipe>();
			if (pipe != null)
			{
				list.Add(pipe);
				foreach (object obj in pipe.ConnectorManager.Connectors)
				{
					Connector connector = (Connector)obj;
                    YArchitech.Revit.SearchSystem searchSystem = new SearchSystem(uidoc, SearchSystemFilter.ByType);
					searchSystem.Run(pipe, connector.Origin);
					foreach (SearchNode searchNode in searchSystem.Nodes)
					{
						Pipe pipe2 = searchNode.Element as Pipe;
						if (pipe2 != null && !list.Contains(pipe2) && YJKRevitTools.isRiserPipe(pipe2))
						{
							list.Add(pipe2);
						}
					}
				}
			}
			return list;
		}

		private List<Autodesk.Revit.DB.View> GetSameTypeViews(UIDocument UIDoc)
		{
			List<Autodesk.Revit.DB.View> list = new List<Autodesk.Revit.DB.View>();
			Autodesk.Revit.DB.View activeView = UIDoc.Document.ActiveView;
			if (activeView.GetParameter("视图分类-父") == null || activeView.GetParameter("视图分类-子") == null)
			{
				return list;
			}
			string b = activeView.GetParameter("视图分类-父").AsString();
			string b2 = activeView.GetParameter("视图分类-子").AsString();
			foreach (Element element in YJKElementFilter.GetElementByCategory(UIDoc.Document, BuiltInCategory.OST_Views))
			{
				ViewPlan viewPlan = ((View)element) as Autodesk.Revit.DB.ViewPlan;
				if (viewPlan != null && viewPlan.GetParameter("视图分类-父") != null && viewPlan.GetParameter("视图分类-子") != null && viewPlan != null && viewPlan.Id != activeView.Id && !viewPlan.IsTemplate && viewPlan.GetParameter("视图分类-父").AsString() == b && viewPlan.GetParameter("视图分类-子").AsString() == b2)
				{
					list.Add(viewPlan);
				}
			}
			return list;
		}

		public string CreateAuxiliaryFrame(bool isAuxiliaryFrame, UIDocument uidoc, XYZ ptCur, double length, double angle, AuxiliaryFrameOperation afOperation)
		{
			XYZ xyz = new XYZ(1.0, Math.Tan(angle * Math.PI / 180.0), 0.0).Normalize();
			XYZ xyz2 = new XYZ(-Math.Tan(angle * Math.PI / 180.0), 1.0, 0.0).Normalize();
			ElementSet elementSet = new ElementSet();
			string result = string.Empty;
			if (length == 0.0)
			{
				return result;
			}
			XYZ xyz3 = ptCur.Add(-AssistFunc.mmToFeet(length) / 2.0 * xyz).Add(AssistFunc.mmToFeet(length) / 2.0 * xyz2);
			XYZ xyz4 = ptCur.Add(-AssistFunc.mmToFeet(length) / 2.0 * xyz).Add(-AssistFunc.mmToFeet(length) / 2.0 * xyz2);
			XYZ xyz5 = ptCur.Add(AssistFunc.mmToFeet(length) / 2.0 * xyz).Add(AssistFunc.mmToFeet(length) / 2.0 * xyz2);
			XYZ xyz6 = ptCur.Add(AssistFunc.mmToFeet(length) / 2.0 * xyz).Add(-AssistFunc.mmToFeet(length) / 2.0 * xyz2);
			List<Line> list = new List<Line>();
			list.Add(YJKLineEx.YJKGetBound(xyz3, xyz4));
			list.Add(YJKLineEx.YJKGetBound(xyz4, xyz6));
			list.Add(YJKLineEx.YJKGetBound(xyz6, xyz5));
			list.Add(YJKLineEx.YJKGetBound(xyz5, xyz3));
			if (isAuxiliaryFrame)
			{
				foreach (Curve curve in list)
				{
					DetailCurve detailCurve = uidoc.Document.Create.NewDetailCurve(uidoc.ActiveView, curve);
					afOperation.SetAuxiliaryFrameCurve(uidoc.Document, detailCurve);
					elementSet.Insert(detailCurve);
				}
				uidoc.Document.Regenerate();
				result = uidoc.Document.CreatYJKGroup(elementSet).Id.ToString();
			}
			return result;
		}

		public List<string> GetLevelUp(Document doc)
		{
			new List<string>();
			return YJKElementFilter.GetElementNameByClass(typeof(Level), doc);
		}

		public List<string> GetPipeType(Document doc)
		{
			new List<string>();
			return YJKElementFilter.GetElementNameByClass(typeof(PipeType), doc);
		}

		public List<string> GetPipingSystemType(Document doc)
		{
			new List<string>();
			return YJKElementFilter.GetElementNameByClass(typeof(PipingSystemType), doc);
		}

		private XYZ GetRiserPipeCenter(Pipe pipe, UIDocument UIDoc)
		{
			Line curve = (pipe.Location as LocationCurve).Curve as Line;
			XYZ hyendPoint = curve.GetEndPoint(0);
			curve.GetEndPoint(1);
			double elevation = UIDoc.ActiveView.GenLevel.Elevation;
			return new XYZ(hyendPoint.X, hyendPoint.Y, elevation);
		}
	}
}
